/************************************************************************************
 *  Copyright 2013 WZITech Corporation. All rights reserved.
 *	
 *	模	块：		AuthenticationInterceptor
 *	包	名：		com.wzitech.gamegold.facade.frontend.interceptor
 *	项目名称：	gamegold-facade-frontend
 *	作	者：		SunChengfei
 *	创建时间：	2014-1-13
 *	描	述：		
 *	更新纪录：	1. SunChengfei 创建于 2014-1-13 下午5:59:36
 * 				
 ************************************************************************************/
package com.hn658.groupshare.frontend.interceptor;

import java.util.List;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.transport.http.AbstractHTTPDestination;
import org.springframework.beans.factory.annotation.Autowired;

import com.hn658.framework.common.interceptor.AbstractInterceptor;
import com.hn658.framework.logging.Logger;
import com.hn658.framework.logging.LoggerFactory;
import com.hn658.framework.logging.enums.LogCategory;
import com.hn658.framework.shared.constants.CommonConstants;
import com.hn658.framework.shared.context.UserContext;
import com.hn658.framework.shared.entity.IUser;
import com.hn658.framework.shared.exception.AccessItfException;
import com.hn658.framework.shared.exception.UserNotLoginException;
import com.hn658.groupshare.account.service.IUserAccountService;
import com.hn658.groupshare.frontend.util.AuthCookieEditor;

/**
 * @author ztjie
 */
public class AuthInInterceptor extends AbstractInterceptor {
	/**
	 * 日志输出
	 */
	private static final Logger logger = LoggerFactory.getLogger(AuthInInterceptor.class);

	/**
	 * 对于列表中Url不做authkey检查
	 */
	private List<String> ignoreAuthUrlsList;
	
	@Autowired
	private IUserAccountService userAccountService;
	
	/**
	 * @param phase
	 */
	public AuthInInterceptor() {
		super(Phase.RECEIVE);
	}

	@Override
	public void handle(Message message) {
		// 获取当前的http请求
		HttpServletRequest request = (HttpServletRequest) message
				.get(AbstractHTTPDestination.HTTP_REQUEST);
		HttpServletResponse response = (HttpServletResponse) message
				.get(AbstractHTTPDestination.HTTP_RESPONSE);
		// 获取当前请求的路径
		String path = (String) message
				.get(org.apache.cxf.message.Message.PATH_INFO);
		logger.debug(LogCategory.SYSTEM, "当前拦截的URL为 {}", path);
		
		//获得登录用户
		IUser user=this.getCurrentUser(request);
		
		if (null != ignoreAuthUrlsList && !ignoreAuthUrlsList.isEmpty()) {
			// 如果当前访问路径在ignoreUrlsList中则跳过检查（注意Url为小写）
			for(String ignoreUrl : ignoreAuthUrlsList){
				if(path.toLowerCase().contains(ignoreUrl.toLowerCase())){
					logger.debug(LogCategory.SYSTEM, "当前请求URL {}在IgnoreUrls列表中,跳过权限检查.", path);
					return;
				}
			}
		}
		if (user == null) {
			throw new UserNotLoginException("请求中包含的cookie {} 没有找到对应的用户信息", null);
		}
		// 重新生成cookie或修改cookie中时间戳
		AuthCookieEditor.saveCookie(request, response);
	}
	
	public IUser getCurrentUser(HttpServletRequest request){
		UserContext.clean();
		try {
			// 当前服务session中没有user对象,从cookie中初始化user到session中
			Cookie cookie = AuthCookieEditor.getCookie(request);
			AuthCookieEditor.cookieToSession(cookie, request.getSession());			
			String authkey = (String) request.getSession().getAttribute(CommonConstants.SERVICE_REQUEST_HEADER_AUTHKEY);
			if(StringUtils.isEmpty(authkey)){
				return null;
			}
			IUser user = userAccountService.getUserByAuthkey(authkey);
			UserContext.setCurrentContext(user, authkey);
			return user;
		} catch (UserNotLoginException e) {
            logger.debug(LogCategory.SYSTEM,"用户还未登录");
            return null;
		} catch (Exception e) {
            logger.error(LogCategory.SYSTEM,"解析用户授权信息时发生异常:{}", ExceptionUtils.getStackTrace(e));
			throw new AccessItfException("解析用户授权信息时发生异常", e);
		}
	}

	/**
	 * @return the ignoreAuthUrlsList
	 */
	public List<String> getIgnoreAuthUrlsList() {
		return ignoreAuthUrlsList;
	}

	/**
	 * @param ignoreAuthUrlsList the ignoreAuthUrlsList to set
	 */
	public void setIgnoreAuthUrlsList(List<String> ignoreAuthUrlsList) {
		this.ignoreAuthUrlsList = ignoreAuthUrlsList;
	}

}
